package com.szholly.pro.watergas_server.ps.monitor;

import java.text.ParseException;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.szholly.data.general.GlobalParameter;
import com.szholly.data.general.RowBase;
import com.szholly.pro.watergas_server.common.data.DataHelper;
import com.szholly.pro.watergas_server.common.data.DataUtil;
import com.szholly.pro.watergas_server.common.util.MonitorDataUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MonitorDataService {
	
	@Autowired
	MonitorDataFormater monitorDataFormater;
	
	@Autowired
	public
	MonitorDataUtil monitorDataUtil;
	
	MonitorWaterType monitorWaterType=new MonitorWaterType();
	/**
	 * 获取指定时间范围内最新一条数据
	 * gislin
	 * 2017年6月22日
	 * @param params
	 * @return
	 * @throws ParseException
	 */
	public MonitorDataModel getLastRealTimeData(Map<String,String> params) throws ParseException{
		String[] outputFields=new String[]{"RTD","AVG","ZS_RTD"};
		MonitorDataModel result = getHistoryDataCommom(params, MonitorDataType.second,outputFields);
		if(result.getData() != null && result.getData().size() > 0){
			List<RowBase> data = new ArrayList<>();
			data.add(result.getData().get(0));
			result.setData(data);
		}
		return result;
	}
	
	/**
	 * 获取实时数据
	 * @param params
	 * @param pageInfo
	 * @return
	 * @throws Exception
	 */
	public MonitorDataModel getRealTimeData(Map<String,String> params) throws Exception {
		String[] outputFields=new String[]{"RTD","AVG","ZS_RTD"};
		MonitorDataType md=monitorWaterType.getWaterType(params.get("WATER_TYPE"), "second");
		MonitorDataModel result = getHistoryDataCommom(params, md,outputFields );
		return result;
	}
	
	/**
	 * 获取分钟数据
	 * @param params
	 * @param pageInfo
	 * @return
	 * @throws Exception
	 */
	public MonitorDataModel getMinuteData(Map<String,String> params) throws Exception {
		String[] outputFields=new String[]{"AVG","ZS_MIN","ZS_MAX","ZS_AVG"};
		MonitorDataType md=monitorWaterType.getWaterType(params.get("WATER_TYPE"), "minute");
		MonitorDataModel result = getHistoryDataCommom(params, md, outputFields);
		return result;
	}
	
	/**
	 * 获取小时数据
	 * @param params
	 * @param pageInfo
	 * @return
	 * @throws Exception
	 */
	public MonitorDataModel getHourData(Map<String,String> params) throws Exception {
		String[] outputFields=new String[]{"AVG","ZS_MIN","ZS_MAX","ZS_AVG"};
		MonitorDataType md=monitorWaterType.getWaterType(params.get("WATER_TYPE"), "hour");
		MonitorDataModel result = getHistoryDataCommom(params, md, outputFields);
		result.setData(formatDateTime(result.getData(), "yyyy-MM-dd HH时"));
		return result;
	}
	
	/**
	 * 获取周期数据
	 * @param params
	 * @param pageInfo
	 * @return
	 * @throws Exception
	 */
	public MonitorDataModel getCycleData(Map<String,String> params) throws Exception {
		String[] outputFields=new String[]{"AVG"};
		MonitorDataType md=monitorWaterType.getWaterType(params.get("WATER_TYPE"), "cycle");
		MonitorDataModel result = getHistoryDataCommom(params, md, outputFields);
		return result;
	}
	
	/**
	 * 获取天数据
	 * @param params
	 * @param pageInfo
	 * @return
	 * @throws Exception
	 */
	public MonitorDataModel getDayData(Map<String,String> params) throws Exception {
		String[] outputFields=new String[]{"AVG","ZS_MIN","ZS_MAX","ZS_AVG"};
		MonitorDataType md=monitorWaterType.getWaterType(params.get("WATER_TYPE"), "day");
		MonitorDataModel result = getHistoryDataCommom(params, md, outputFields);
		result.setData(formatDateTime(result.getData(), "yyyy-MM-dd"));
		return result;
	}
	
	/**
	 * 获取月数据
	 * @param params
	 * @param pageInfo
	 * @return
	 * @throws Exception
	 */
	public MonitorDataModel getMonthData(Map<String,String> params) throws Exception {
		String[] outputFields=new String[]{"AVG","ZS_MIN","ZS_MAX","ZS_AVG"};
		MonitorDataType md=monitorWaterType.getWaterType(params.get("WATER_TYPE"), "day");
		MonitorDataModel result = getHistoryDataCommom(params, md, outputFields);
		result.setData(formatDateTime(result.getData(), "yyyy-MM-dd"));
		return result;
	}
	
	/**
	 * 获取周数据报表
	 * @param params
	 * @param pageInfo
	 * @return
	 * @throws Exception
	 */
	public MonitorDataModel getWeekDataReport(Map<String,String> params) throws Exception {
		String[] outputFields=new String[]{"AVG","ZS_MIN","ZS_MAX","ZS_AVG"};
		MonitorDataType md=monitorWaterType.getWaterType(params.get("WATER_TYPE"), "day");
		MonitorDataModel result = getReportCommon(params, md, outputFields);
		result.setData(formatDateTime(result.getData(), "yyyy-MM-dd"));
		return result;
	}
	
	/**
	 * 获取月数据报表
	 * @param params
	 * @param pageInfo
	 * @return
	 * @throws Exception
	 */
	public MonitorDataModel getMonthDataReport(Map<String,String> params) throws Exception {
		String[] outputFields=new String[]{"AVG","ZS_MIN","ZS_MAX","ZS_AVG"};
		MonitorDataType md=monitorWaterType.getWaterType(params.get("WATER_TYPE"), "day");
		MonitorDataModel result = getReportCommon(params, md, outputFields);
		result.setData(formatDateTime(result.getData(), "yyyy-MM-dd"));
		return result;
	}
	
	/**
	 * 获取季度数据报表
	 * @param params
	 * @param pageInfo
	 * @return
	 * @throws Exception
	 */
	public MonitorDataModel getQuarterDataReport(Map<String,String> params) throws Exception {
		String[] outputFields=new String[]{"AVG","ZS_MIN","ZS_MAX","ZS_AVG"};
		MonitorDataType md=monitorWaterType.getWaterType(params.get("WATER_TYPE"), "month");
		MonitorDataModel result = getReportCommon(params,md, outputFields);
		result.setData(formatDateTime(result.getData(), "yyyy-MM月"));
		return result;
	}
	
	/**
	 * 获取年数据报表
	 * @param params
	 * @param pageInfo
	 * @return
	 * @throws Exception
	 */
	public MonitorDataModel getYearDataReport(Map<String,String> params) throws Exception {
		String[] outputFields=new String[]{"AVG","ZS_MIN","ZS_MAX","ZS_AVG"};
		MonitorDataType md=monitorWaterType.getWaterType(params.get("WATER_TYPE"), "month");
		MonitorDataModel result = getReportCommon(params, md, outputFields);
		result.setData(formatDateTime(result.getData(), "yyyy-MM月"));
		return result;
	}
	/**
	 * 获取日数据报表
	 * @param params
	 * @param pageInfo
	 * @return
	 * @throws Exception
	 */
	public MonitorDataModel getDayDataReport(Map<String,String> params) throws Exception {
		String[] outputFields=new String[]{"AVG","ZS_MIN","ZS_MAX","ZS_AVG"};
		MonitorDataType md=monitorWaterType.getWaterType(params.get("WATER_TYPE"), "hour");
		MonitorDataModel result = getReportCommon(params, md, outputFields);
		result.setData(formatDateTime(result.getData(), "yyyy-MM-dd HH时"));
		return result;
	}
	
	
	/**
	 * 获取工业污染源-烟气排放量月报表数据
	 * @param params
	 * @param pageInfo
	 * @return
	 * @throws Exception
	 */
	public List<RowBase> getAirDisplaceMonthReport(Map<String,String> params) throws Exception {
		String mn = params.get("MN");
		String start = params.get("START");
		String end = params.get("END");
        
		String sql ="select t1.companyname,t1.pointname,t.* from displace_report_month_air t left join "
				+" (select t1.name as companyname,t.name as pointname,t2.device_num from BC_SITE_INFO t"
		        +" left join BC_ENTERPRISE_ATTR t1 on t1.exp_no = t.wwtp_id "
				+" left join BC_COLLECTION_INFO t2 on t2.site_id = t.exp_no"
		        +" where t.station_category = '4') t1 on t1.device_num = t.mn"
		        +" where t.datatime >= to_date('" + start + "','YYYY-MM-DD HH24:MI:SS') "
		        + "and t.datatime < to_date('" + end + "','YYYY-MM-DD HH24:MI:SS')";
		
		if(!mn.equals("all")){
			sql += "and t.mn = '" + mn + "'";
		}

		List<RowBase> result = DataUtil.getSelectRows(sql, null);
		return result;
	}
	
	/**
	 * 对时间字段进行格式化
	 * @param result
	 * @param fmt
	 * @return
	 */
	private List<RowBase> formatDateTime(List<RowBase> result,String fmt){
		SimpleDateFormat sf = new SimpleDateFormat(fmt);
		for(RowBase row : result){
			try {
				Date date = row.getDate("DATATIME");
				row.setValue("DATATIME", sf.format(date));
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
		return result;
	}
	
	/**
	 * 通用的获取历史数据方法
	 * 实时，分钟，小时，周期，和天都可以共用，报表除外
	 * @param params 查询参数：MN,START,END,waterType
	 * @param tableName 要查询的表名
	 * @param dataField 要查询的数据字段，实时数据为RTD，其他为AVG，同时也作为行转列的依据
	 * @return 返回的结果会进行行转列，同一个时间，不同参数的回合并成一行
	 * 			并进行小数位格式化，添加报警信息
	 * @throws ParseException 
	 */
	private MonitorDataModel getHistoryDataCommom(Map<String,String> params,MonitorDataType dataType,String[] dataFields) throws ParseException{
		
		String mn = params.get("MN");
		String start = params.get("START");
		String end = params.get("END");
		String waterType = params.get("WATER_TYPE");
		if(mn == null ||mn.equals("")){
			return null;
		}
		
		String parmToChecks = params.get("PARMS");
		String[] parms = parmToChecks.split(",");
		
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		
		Date startDate = sf.parse(start);
		Date endDate = sf.parse(end);
		
		MonitorDataModel result = monitorDataUtil.getHistoryData(mn, startDate, endDate, dataType.getTableName(), parms, dataFields);
		result = processHistoryData(result, waterType, mn, parms, dataFields,dataType,startDate,endDate);
		
		return result;
	}
	
	/**
	 * 获取报表数据
	 * 需要统计最大最小值和均值
	 * 以及计算综合污染指数和水质类别
	 * @param params
	 * @param tableName
	 * @param dataFields
	 * @return
	 * @throws ParseException
	 */
	private MonitorDataModel getReportCommon(Map<String,String> params,MonitorDataType dataType,String[] dataFields) throws ParseException{
		String mn = params.get("MN");
		String start = params.get("START");
		String end = params.get("END");
		String waterType = params.get("WATER_TYPE");
		if(mn == null ||mn.equals("")){
			return null;
		}
		
		List<String> rowToColFields = new ArrayList<String>();
		for(String field : dataFields){
			rowToColFields.add(field);
		}
		
		String parmToChecks = params.get("PARMS");
		String[] parms = parmToChecks.split(",");
		
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		
		Date startDate = sf.parse(start);
		Date endDate = sf.parse(end);
		
		MonitorDataModel monitorDataModel = monitorDataUtil.getHistoryData(mn, startDate, endDate, dataType.getTableName(), parms, dataFields);
		monitorDataModel = processHistoryData(monitorDataModel, waterType, mn, parms, dataFields,dataType,startDate,endDate);
		
		return monitorDataModel;
	}
	
	/**
	 * 二次加工历史数据
	 * 行转列
	 * 小数点格式化
	 * 增加报警信息
	 * 数据缺失留白
	 * gislin
	 * 2017年4月26日
	 * @param monitorDataModel 待处理的数据
	 * @param waterType 业务类型，区分地表水，污水工业污染源
	 * @param mn 站点mn号
	 * @param parms 要处理的污染物code数组
	 * @param dataFields 要查的数据字段数组，比如AVG,COU,RTD等
	 * @param dataType 
	 * @param startDate
	 * @param endDate
	 * @return
	 */
	public MonitorDataModel processHistoryData(MonitorDataModel monitorDataModel,String waterType,String mn,String[] parms,String[] dataFields,MonitorDataType dataType,Date startDate,Date endDate){
		
		long startTime=System.currentTimeMillis();   //获取开始时间
		long endTime = System.currentTimeMillis(); //获取结束时间
		
		List<String> rowToColFields = new ArrayList<String>();
		for(String field : dataFields){
			rowToColFields.add(field);
		}
		rowToColFields.add("FLAG");
		
		startTime=System.currentTimeMillis(); 
		monitorDataModel.setData(DataHelper.RowToCol(monitorDataModel.getData(), "DATATIME", rowToColFields, "PARMNAME"));
		endTime = System.currentTimeMillis();
		System.out.println("行转列时间： "+(endTime-startTime)+"ms");
		
		startTime=System.currentTimeMillis(); 
		monitorDataModel = monitorDataUtil.generaMinMaxAvg(monitorDataModel, parms, dataFields, waterType);
		endTime = System.currentTimeMillis();
		System.out.println("统计最大最小值耗时： "+(endTime-startTime)+"ms");
		
		startTime=System.currentTimeMillis(); 
		monitorDataModel = monitorDataUtil.generaWaterStandardInfo(this, monitorDataModel, "AVG", parms);
		endTime = System.currentTimeMillis();
		System.out.println("统计水质类别耗时： "+(endTime-startTime)+"ms");
		
		startTime=System.currentTimeMillis(); 
		monitorDataModel = MonitorDataFormater.getInstance().numPointFormat(monitorDataModel, parms, waterType);
		endTime = System.currentTimeMillis();
		System.out.println("小数点格式化： "+(endTime-startTime)+"ms");
		
		startTime=System.currentTimeMillis(); 
		monitorDataModel = MonitorDataFormater.getInstance().unitFormat(monitorDataModel, parms, waterType);
		endTime = System.currentTimeMillis();
		System.out.println("单位格式化： "+(endTime-startTime)+"ms");
		
		startTime=System.currentTimeMillis();  
		monitorDataModel.setData(monitorDataUtil.GenerateAlarmInfo(monitorDataModel.getData(), parms, mn, "AVG"));
		endTime = System.currentTimeMillis(); 
		System.out.println("报警数据生成： "+(endTime-startTime)+"ms");
		
		startTime=System.currentTimeMillis();  
		monitorDataModel.setData(monitorDataUtil.fixMissData(monitorDataModel.getData(),waterType, dataType, startDate, endDate));
		endTime = System.currentTimeMillis(); 
		System.out.println("数据缺失补全： "+(endTime-startTime)+"ms");
		
		monitorDataModel.setData(monitorDataUtil.clearMonitorData(monitorDataModel.getData()));
		
		return monitorDataModel;
	}
	
	/**
	 * 获取水质标准
	 * @param params 'SURFACE_WATER' 表示地表水
	 * @return
	 */
	public List<RowBase> getWaterQualityStandards(String category){
		String sql = "select * from BC_QUALITY_STANDARD t where 1=1";
		
		
		List<GlobalParameter> listParams = new ArrayList<>();
		sql += " and t.category=@category";
		listParams.add(new GlobalParameter("category",category));
		
		return DataUtil.getSelectRows(sql, listParams);
	}
}
